package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSkuVo;
import com.spzx.product.api.domain.SkuPriceVo;
import org.apache.tomcat.util.buf.UEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements ICartService {
    @Autowired
    private RemoteProductService remoteProductService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {

        //获取当前用户id
        Long userId = SecurityContextHolder.getUserId();
        //根据userId获取购物车key
        String cartKey = getCartKey(userId);
        //判断购物车中是否存在商品skuId
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        String hashKey = skuId.toString();
        Integer threshold = 5;
        if (hashOps.hasKey(hashKey)) {
            //如果商品已存在,数量+1
            CartInfo cartInfo = hashOps.get(hashKey);
            int totalCount = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalCount > threshold ? threshold : totalCount);
            hashOps.put(hashKey, cartInfo);
        } else {
            //判断购物车商品种类（不同SKU）总数大于50件
            Long count = hashOps.size();
            if (++count > 3) {
                throw new RuntimeException("商品种类数量超过上限！");
            }
            //如果商品不存在,则在购物车中创建当前商品
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);

            //远程调用商品模块，获取商品sku信息
            R<ProductSkuVo> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSkuVo productSkuVo = productSkuResult.getData();

            cartInfo.setCartPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuName(productSkuVo.getSkuName());
            cartInfo.setThumbImg(productSkuVo.getThumbImg());
            cartInfo.setCreateTime(new Date());

            hashOps.put(hashKey, cartInfo);
        }


    }

    @Override
    public List<CartInfo> getCartList() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            List<CartInfo> infoList = cartInfoList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return infoList;
        }
        return cartInfoList;
    }

    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations hashOps = redisTemplate.boundHashOps(cartKey);
        hashOps.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        if (hashOps.hasKey(skuId.toString())) {
            CartInfo cartInfo = hashOps.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            hashOps.put(skuId.toString(), cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        hashOps.values().stream().forEach(cartInfo -> {
            cartInfo.setIsChecked(isChecked);
            hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
        });
    }

    @Override
    public void clearCart() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getCartCheckedList() {

        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        List<CartInfo> cartInfoListFromRedis = redisTemplate.opsForHash().values(cartKey);

        if (!CollectionUtils.isEmpty(cartInfoListFromRedis)) {
            return cartInfoListFromRedis.stream().filter(
                    cartInfo -> cartInfo.getIsChecked().intValue() == 1
            ).collect(Collectors.toList());
        }
//        return null;
        return new ArrayList<>();

    }

    @Override
    public Boolean deleteCartCheckedList() {
        //获取用户id
        Long userId = SecurityContextHolder.getUserId();
        //获取购物车key
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //删除购物车中被选中的商品
        hashOps.values().stream().forEach(cartInfo -> {
            if (cartInfo.getIsChecked().intValue() == 1) {
                hashOps.delete(cartInfo.getSkuId().toString());
            }
        });

        return true;
    }

    //更新购物车商品价格
    @Override
    public Boolean updateCartPrice() {

        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);

        //获取购物车中的商品列表
        List<CartInfo> cartInfoList = hashOps.values();
        cartInfoList.stream().forEach(cartInfo -> {
            //获取实际商品价格
            R<SkuPriceVo> skuPriceVoResult = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER);
            if (R.FAIL == skuPriceVoResult.getCode()) {
                throw new ServiceException(skuPriceVoResult.getMsg());
            }
            SkuPriceVo skuPriceVo = skuPriceVoResult.getData();
//                cartInfo.setCartPrice(skuPriceVo.getSalePrice());//放入购物车时的价格
            if(skuPriceVo.getSalePrice().compareTo(cartInfo.getSkuPrice()) != 0) {
                cartInfo.setSkuPrice(skuPriceVo.getSalePrice());//实时价格
                hashOps.put(cartInfo.getSkuId().toString(),cartInfo);
            }

        });
        return true;

    }


    private String getCartKey(Long userId) {
        return "user:cart:" + userId;
    }
}
